%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Start of pgf-umlcd.sty
%
% Some macros for UML Class Diagrams.
% Home page of project: http://pgf-umlcd.googlecode.com/
% Author: Xu Yuan <xu@informatik.hu-berlin.de>, Humboldt University, Berlin
% Style from: http://www.ibm.com/developerworks/cn/rational/r-uml/
%

\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{pgf-umlcd}[2011/10/01 v0.3dev Some LaTeX macros for
UML Class Diagrams.]

\RequirePackage{tikz}
%\usepackage{ulem}
\RequirePackage{ulem}

\usetikzlibrary{arrows,shapes.multipart,backgrounds,fit}
\tikzstyle{help lines}+=[blue!50,very thin,dashed]

\newcommand{\umltextcolor}{black}
\newcommand{\umldrawcolor}{purple}
\newcommand{\umlfillcolor}{yellow!20}
\tikzstyle{umlcolor}=[color=\umldrawcolor,fill=\umlfillcolor,text=\umltextcolor]
\tikzstyle{umlcd style}=[umlcolor, >=angle 90]

\tikzstyle{package}=[matrix, column sep=1mm, row sep=1cm, node distance=2cm]
\tikzstyle{packagename}=[rectangle, minimum height=2em]

\tikzstyle{umlcd style implement line}=[color=\umldrawcolor, open triangle 45-,dashed]
\tikzstyle{objectline}=[color=\umldrawcolor, diamond->]
\tikzstyle{umlcd style inherit line}=[color=\umldrawcolor, open triangle 45-]
\tikzstyle{splitline}=[color=\umldrawcolor, dotted,font=\itshape]

\tikzstyle{umlcd style class}=[rectangle split, rectangle split parts=3, 
    every text node part/.style={text centered},
    draw, minimum height=2em, umlcolor, minimum width=2cm, text width=5cm,
minimum height=1cm, node distance=2cm]

% by whg 2014-06-29 星期日 19:02
%\tikzstyle{every node}=[font=\small\sffamily]
%\tikzstyle{every node}=[font=\small\sffamily\sansmath]
%\tikzstyle{every node}=[font=\scriptsize\ttfamily]
%\tikzstyle{every node}=[font=\tiny\ttfamily]
\tikzstyle{every node}=[font=\small\ttfamily]

\tikzstyle{umlcd style dashed line}=[color=\umldrawcolor, >=angle 90,dashed]

\tikzstyle{umlcd style school}=[]
\newif\ifschool\schoolfalse
\DeclareOption{school}{\tikzstyle{umlcd style school}=[rounded corners] \schooltrue}
\newif\ifsimplified\simplifiedfalse
\DeclareOption{simplified}{\simplifiedtrue}
\ProcessOptions\relax


% declare layers
\pgfdeclarelayer{background}
\pgfdeclarelayer{connectionlayers}
\pgfsetlayers{background,connectionlayers,main}

\newcounter{umlcdClassAttributesNum}
\newcounter{umlcdClassOperationsNum}
\newcounter{umlcdClassAbstractClassNum}
\newcounter{umlcdClassInterfaceNum}
\newcounter{umlcdClassSplitPartNum}

\def\umlcdPackageFit{}

\newenvironment{class}[3][]%
{
    \begin{classAndInterfaceCommon}{#1}{#2}{#3}
    }%
    {\calcuateNumberOfParts{}
        \node[this umlcd style, anchor=north] (\umlcdClassName) at (\umlcdClassPos)
        {\textbf{\umlcdClassName}
            \insertAttributesAndOperations{}
        };

    \end{classAndInterfaceCommon}
}

\newenvironment{interface}[3][]%
{
    \begin{classAndInterfaceCommon}{#1}{#2}{#3}
    }%
    {\calcuateNumberOfParts{}
        \node[this umlcd style, anchor=north] (\umlcdClassName) at (\umlcdClassPos)
        {$<<$interface$>>$ \\ \textbf{\umlcdClassName}
            \insertAttributesAndOperations{}
        };

    \end{classAndInterfaceCommon}
}

\newenvironment{abstractclass}[3][]%
{
    \begin{classAndInterfaceCommon}{#1}{#2}{#3}
    }%
    {\calcuateNumberOfParts{}
        \node[this umlcd style, anchor=north] (\umlcdClassName) at (\umlcdClassPos)
        {$<<$abstract$>>$ \\ \textbf{\umlcdClassName}
            \insertAttributesAndOperations{}
        };

    \end{classAndInterfaceCommon}
}

% TODO: here the name of \umlcdClassName and \umlObjectName should be
% switched, it is only for reusing \classAndInterfaceCommon at the
% moment.
\newenvironment{object}[3][]%
{
    \begin{classAndInterfaceCommon}{#1}{#2}{#3}
        \def\@instanceOf{}
        \def\@@instanceOf{}
    }%
    {
        % customized
        \ifsimplified
        \calcuateNumberOfParts{}
        \else
        \ifnum\c@umlcdClassOperationsNum>0
        \setcounter{umlcdClassSplitPartNum}{3}
        \protected@xdef\umlcdSplitPart{3}
        \else
        \setcounter{umlcdClassSplitPartNum}{2}
        \protected@xdef\umlcdSplitPart{2}
        \fi
        \fi

        \ifx\@instanceOf\@@instanceOf
        \def\umldObjectName{\umlcdClassName}
        \else
        \def\umldObjectName{\umlcdClassName : \@instanceOf}
        \fi

        \node[this umlcd style, anchor=north, umlcd style school] (\umlcdClassName) at (\umlcdClassPos)
        { \ifschool
            \textbf{\umldObjectName}
            \else 
            \underline{\textbf{\umldObjectName}}
            \fi
            \insertAttributesAndOperations{}
        };

    \end{classAndInterfaceCommon}
}

\newcommand*{\insertAttributesAndOperations}
{
    \ifnum\c@umlcdClassSplitPartNum>1
    \nodepart{second}
    \fi
    \umlcdClassAttributes
    \ifnum\c@umlcdClassSplitPartNum>2
    \nodepart{third}
    \fi
    \umlcdClassOperations
}

\newcommand*{\calcuateNumberOfParts}
{
    % calcuate the number of parts
    \ifsimplified
    \setcounter{umlcdClassSplitPartNum}{1}
    \ifnum\c@umlcdClassAttributesNum>0
    \stepcounter{umlcdClassSplitPartNum}
    \fi
    \ifnum\c@umlcdClassOperationsNum>0
    \stepcounter{umlcdClassSplitPartNum}
    \fi
    \else
    \setcounter{umlcdClassSplitPartNum}{3}% three parts by default
    \fi

    \protected@xdef\umlcdSplitPart{3}
    \ifnum\c@umlcdClassSplitPartNum=1
    \protected@xdef\umlcdSplitPart{1}
    \fi
    \ifnum\c@umlcdClassSplitPartNum=2
    \protected@xdef\umlcdSplitPart{2}
    \fi
}

\newenvironment*{classAndInterfaceCommon}[3]
{
    \def\umlcdClassName{#2}%
    \def\umlcdClassPos{#3}
    \def\umlcdClassAttributes{}%
    \def\umlcdClassOperations{}%
    \def\umlcdClassAbstractClass{}%
    \def\umlcdClassInterface{}%
    \setcounter{umlcdClassAttributesNum}{0}%
    \setcounter{umlcdClassOperationsNum}{0}%
    \setcounter{umlcdClassAbstractClassNum}{0}%
    \setcounter{umlcdClassInterfaceNum}{0}%
    \tikzstyle{this umlcd style}=[umlcd style class, rectangle split
    parts=\umlcdSplitPart, #1]
}%
{
    %% connections
    \begin{pgfonlayer}{connectionlayers}
        \ifnum\c@umlcdClassAbstractClassNum>0
        \foreach \c in \umlcdClassAbstractClass {
            \draw [umlcd style inherit line] (\c) -- (\umlcdClassName);
        }
        \fi

        \ifnum\c@umlcdClassInterfaceNum>0
        \foreach \c in \umlcdClassInterface {
            \draw [umlcd style implement line] (\c) -- (\umlcdClassName);
        }
        \fi
    \end{pgfonlayer}

    %% add to fit
    \let\umlcdPackageFitOld\umlcdPackageFit
    \protected@xdef\umlcdPackageFit{\umlcdPackageFitOld (\umlcdClassName)}
}

\newcommand{\attribute}[1]{%
    \ifnum\c@umlcdClassAttributesNum=0
    \protected@xdef\umlcdClassAttributes{#1}
    \else
    \let\umlcdClassAttributesOld\umlcdClassAttributes
    \protected@xdef\umlcdClassAttributes{\umlcdClassAttributesOld \ \newline #1}
    \fi
    \stepcounter{umlcdClassAttributesNum}
}

\newcommand{\operation}[2][1]{%
    \stepcounter{umlcdClassOperationsNum}

    \def\virtualoperation{#2}
    \ifnum0=#1
    \def\virtualoperation{\textit{#2}}
    \fi

    \ifnum\c@umlcdClassOperationsNum=1
    \protected@xdef\umlcdClassOperations{\virtualoperation}
    \else
    \let\umlcdClassOperationsOld\umlcdClassOperations
    \protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
    \virtualoperation}
    \fi
}

% by whg 2014-06-29 星期日 18:08 
% attribute
\newcommand{\publicattribute}[1]{%
    \ifnum\c@umlcdClassAttributesNum=0
    \protected@xdef\umlcdClassAttributes{+#1}
    \else
    \let\umlcdClassAttributesOld\umlcdClassAttributes
    \protected@xdef\umlcdClassAttributes{\umlcdClassAttributesOld \ \newline +#1}
    \fi
    \stepcounter{umlcdClassAttributesNum}
}

\newcommand{\privateattribute}[1]{%
    \ifnum\c@umlcdClassAttributesNum=0
    \protected@xdef\umlcdClassAttributes{-#1}
    \else
    \let\umlcdClassAttributesOld\umlcdClassAttributes
    \protected@xdef\umlcdClassAttributes{\umlcdClassAttributesOld \ \newline -#1}
    \fi
    \stepcounter{umlcdClassAttributesNum}
}
\newcommand{\protectedattribute}[1]{%
    \ifnum\c@umlcdClassAttributesNum=0
    \protected@xdef\umlcdClassAttributes{\##1}
    \else
    \let\umlcdClassAttributesOld\umlcdClassAttributes
    \protected@xdef\umlcdClassAttributes{\umlcdClassAttributesOld \ \newline \##1}
    \fi
    \stepcounter{umlcdClassAttributesNum}
}

% static attribute
\newcommand{\publicstaticattribute}[1]{%
    \ifnum\c@umlcdClassAttributesNum=0
    \protected@xdef\umlcdClassAttributes{+\uline{#1}}
    \else
    \let\umlcdClassAttributesOld\umlcdClassAttributes
    \protected@xdef\umlcdClassAttributes{\umlcdClassAttributesOld \ \newline +\uline{#1}}
    \fi
    \stepcounter{umlcdClassAttributesNum}
}

\newcommand{\privatestaticattribute}[1]{%
    \ifnum\c@umlcdClassAttributesNum=0
    \protected@xdef\umlcdClassAttributes{-#1}
    \else
    \let\umlcdClassAttributesOld\umlcdClassAttributes
    \protected@xdef\umlcdClassAttributes{\umlcdClassAttributesOld \ \newline -\uline{#1}}
    \fi
    \stepcounter{umlcdClassAttributesNum}
}
\newcommand{\protectedstaticattribute}[1]{%
    \ifnum\c@umlcdClassAttributesNum=0
    \protected@xdef\umlcdClassAttributes{\#\uline{#1}}
    \else
    \let\umlcdClassAttributesOld\umlcdClassAttributes
    \protected@xdef\umlcdClassAttributes{\umlcdClassAttributesOld \ \newline \#\uline{#1}}
    \fi
    \stepcounter{umlcdClassAttributesNum}
}

% operation
\newcommand{\publicoperation}[1]{%
    \stepcounter{umlcdClassOperationsNum}

    \def\virtualoperation{+#1}

    \ifnum\c@umlcdClassOperationsNum=1
    \protected@xdef\umlcdClassOperations{\virtualoperation}
    \else
    \let\umlcdClassOperationsOld\umlcdClassOperations
    \protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
    \virtualoperation}
    \fi
}

\newcommand{\privateoperation}[1]{%
    \stepcounter{umlcdClassOperationsNum}

    \def\virtualoperation{-#1}

    \ifnum\c@umlcdClassOperationsNum=1
    \protected@xdef\umlcdClassOperations{\virtualoperation}
    \else
    \let\umlcdClassOperationsOld\umlcdClassOperations
    \protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
    \virtualoperation}
    \fi
}

\newcommand{\protectedoperation}[1]{%
    \stepcounter{umlcdClassOperationsNum}

    \def\virtualoperation{\##1}

    \ifnum\c@umlcdClassOperationsNum=1
    \protected@xdef\umlcdClassOperations{\virtualoperation}
    \else
    \let\umlcdClassOperationsOld\umlcdClassOperations
    \protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
    \virtualoperation}
    \fi
}

% virtual operation
\newcommand{\publicvirtualoperation}[1]{%
    \stepcounter{umlcdClassOperationsNum}

    \def\virtualoperation{+\textit{#1}}

    \ifnum\c@umlcdClassOperationsNum=1
    \protected@xdef\umlcdClassOperations{\virtualoperation}
    \else
    \let\umlcdClassOperationsOld\umlcdClassOperations
    \protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
    \virtualoperation}
    \fi
}

\newcommand{\privatevirtualoperation}[1]{%
    \stepcounter{umlcdClassOperationsNum}

    \def\virtualoperation{-\textit{#1}}

    \ifnum\c@umlcdClassOperationsNum=1
    \protected@xdef\umlcdClassOperations{\virtualoperation}
    \else
    \let\umlcdClassOperationsOld\umlcdClassOperations
    \protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
    \virtualoperation}
    \fi
}

\newcommand{\protectedvirtualoperation}[1]{%
    \stepcounter{umlcdClassOperationsNum}

    \def\virtualoperation{\#\textit{#1}}

    \ifnum\c@umlcdClassOperationsNum=1
    \protected@xdef\umlcdClassOperations{\virtualoperation}
    \else
    \let\umlcdClassOperationsOld\umlcdClassOperations
    \protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
    \virtualoperation}
    \fi
}

% static operation
\newcommand{\publicstaticoperation}[1]{%
    \stepcounter{umlcdClassOperationsNum}

    \def\virtualoperation{+\uline{#1}}

    \ifnum\c@umlcdClassOperationsNum=1
    \protected@xdef\umlcdClassOperations{\virtualoperation}
    \else
    \let\umlcdClassOperationsOld\umlcdClassOperations
    \protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
    \virtualoperation}
    \fi
}

\newcommand{\privatestaticoperation}[1]{%
    \stepcounter{umlcdClassOperationsNum}

    \def\virtualoperation{-\uline{#1}}

    \ifnum\c@umlcdClassOperationsNum=1
    \protected@xdef\umlcdClassOperations{\virtualoperation}
    \else
    \let\umlcdClassOperationsOld\umlcdClassOperations
    \protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
    \virtualoperation}
    \fi
}

\newcommand{\protectedstaticoperation}[1]{%
    \stepcounter{umlcdClassOperationsNum}

    \def\virtualoperation{\#\uline{#1}}

    \ifnum\c@umlcdClassOperationsNum=1
    \protected@xdef\umlcdClassOperations{\virtualoperation}
    \else
    \let\umlcdClassOperationsOld\umlcdClassOperations
    \protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
    \virtualoperation}
    \fi
}
% by whg end

\newcommand{\inherit}[1]
{
    \stepcounter{umlcdClassAbstractClassNum}
    \ifnum\c@umlcdClassAbstractClassNum=1
    \protected@xdef\umlcdClassAbstractClass{#1}
    \else
    \let\umlcdClassAbstractClassOld\umlcdClassAbstractClass
    \protected@xdef\umlcdClassAbstractClass{\umlcdClassAbstractClassOld,#1}
    \fi
}

\newcommand{\implement}[1]
{
    \stepcounter{umlcdClassInterfaceNum}
    \ifnum\c@umlcdClassInterfaceNum=1
    \protected@xdef\umlcdClassInterface{#1}
    \else
    \let\umlcdClassInterfaceOld\umlcdClassInterface
    \protected@xdef\umlcdClassInterface{\umlcdClassInterfaceOld, #1}
    \fi
}

\newcommand{\instanceOf}[1]{\def\@instanceOf{#1}}

\newcommand{\association}[6]{
    \draw [umlcd style] (#1) -- (#4)
    node[very near start, above]{#2}
    node[very near start, below]{#3}
    node[very near end, above]{#5}
    node[very near end, below]{#6};
}

\newcommand{\unidirectionalAssociation}[4]{
    \draw [umlcd style, ->] (#1) -- (#4)
    node[very near end, above]{#2}
    node[very near end, below]{#3};
}

\newcommand{\aggregation}[5]
{
    \draw[umlcd style, open diamond->] (#1) -- (#5)
    node[very near start, below]{#2}
    node[midway, above]{#3}
    node[very near end, below]{#4};
}

\newcommand{\composition}[5]
{
    \draw[umlcd style, fill=\umldrawcolor, diamond->] (#1) -- (#5)
    node[very near start, below]{#2}
    node[midway, above]{#3}
    node[very near end, below]{#4};
}

\newenvironment{package}[1]{
    \def\umlcdPackageFit{}
    \def\umlcdPackageName{#1}
}{
    \begin{pgfonlayer}{background}
        \node[umlcd style, draw, inner sep=0.5cm, fit = \umlcdPackageFit] (\umlcdPackageName) {};
        \node[umlcd style, draw, outer ysep=-0.5, anchor=south west] (\umlcdPackageName caption) at
        (\umlcdPackageName.north west) {\umlcdPackageName};
    \end{pgfonlayer}
}

\newcommand{\switchUmlcdSchool}{
    \ifschool
    \tikzstyle{umlcd style school}=[]
    \schoolfalse
    \else
    \tikzstyle{umlcd style school}=[rounded corners]
    \schooltrue
    \fi
}

\pgfdeclareshape{umlcdnote}{
    \inheritsavedanchors[from=rectangle] % this is nearly a rectangle
    \inheritanchorborder[from=rectangle]
    \inheritanchor[from=rectangle]{center}
    \inheritanchor[from=rectangle]{north}
    \inheritanchor[from=rectangle]{south}
    \inheritanchor[from=rectangle]{west}
    \inheritanchor[from=rectangle]{east}
    % ... and possibly more
    \backgroundpath{% this is new
        % store lower right in xa/ya and upper right in xb/yb
        \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
        \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
        % compute corner of flipped page
        \pgf@xc=\pgf@xb \advance\pgf@xc by-10pt % this should be a parameter
        \pgf@yc=\pgf@yb \advance\pgf@yc by-10pt
        % construct main path
        \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
        \pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
        \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yb}}
        \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
        \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
        \pgfpathclose
        % add little corner
        \pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@yb}}
        \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
        \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
        \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
    }
}

\newcommand{\umlnote}[1][]{
    \node[umlcd style, anchor=north, draw,shape=umlcdnote, text width=4cm, #1]
}

%%% End of pgf-umlcd.sty
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
